#include "aviutils.h"
#include <qdebug.h>
AviUtils::AviUtils()
{
    mFileIO = new FileIO();
}

void AviUtils::write_avi_header(QByteArray *out, gwavi_header_t *avi_header)
{
    long marker,t;
    mFileIO->write_chars_bin(out,"avih",4);

    //insert size
    marker = out->length();

    mFileIO->write_int(out,avi_header->time_delay);

    mFileIO->write_int(out,avi_header->data_rate);

    mFileIO->write_int(out,avi_header->reserved);

    mFileIO->write_int(out,avi_header->flags);

    mFileIO->write_int(out,avi_header->number_of_frames);

    mFileIO->write_int(out,avi_header->initial_frames);

    mFileIO->write_int(out,avi_header->data_streams);

    mFileIO->write_int(out,avi_header->buffer_size);

    mFileIO->write_int(out,avi_header->width);

    mFileIO->write_int(out,avi_header->height);

    mFileIO->write_int(out,avi_header->time_scale);

    mFileIO->write_int(out,avi_header->playback_data_rate);

    mFileIO->write_int(out,avi_header->starting_time);

    mFileIO->write_int(out,avi_header->data_length);

    t = out->length();

    mFileIO->insert_int(out,marker,(quint32)(t-marker));
}

void AviUtils::write_stream_header(QByteArray *out, gwavi_stream_header_t *stream_header)
{
    long marker,t;
    mFileIO->write_chars_bin(out,"strh",4);

    marker = out->length();

    mFileIO->write_chars_bin(out,stream_header->data_type.toLatin1().data(),4);

    if(stream_header->codec.isNull() || stream_header->codec.isEmpty())
    {
        mFileIO->write_int(out,(uint)0);
    }
    else
    {
        mFileIO->write_chars_bin(out,stream_header->codec.toLatin1().data(),4);
    }
//    mFileIO->write_chars_bin(out,stream_header->codec.toLatin1().data(),4);

    mFileIO->write_int(out,stream_header->flags);

    mFileIO->write_int(out,stream_header->priority);

    mFileIO->write_int(out,stream_header->initial_frames);

    mFileIO->write_int(out,stream_header->time_scale);

    mFileIO->write_int(out,stream_header->data_rate);

    mFileIO->write_int(out,stream_header->start_time);

    mFileIO->write_int(out,stream_header->data_length);

    mFileIO->write_int(out,stream_header->buffer_size);

    mFileIO->write_int(out,stream_header->quality);

    mFileIO->write_int(out,stream_header->sample_size);

    mFileIO->write_short(out,stream_header->left);

    mFileIO->write_short(out,stream_header->top);

    mFileIO->write_short(out,stream_header->right);

    mFileIO->write_short(out,stream_header->bottom);

    t = out->length();

    mFileIO->insert_int(out,marker,(uint)(t-marker));
}

void AviUtils::write_stream_format_v(QByteArray *out, gwavi_stream_format_v_t *stream_format_v)
{
    long marker,t;
    uint i;

    mFileIO->write_chars_bin(out,"strf",4);

    marker = out->length();

    mFileIO->write_int(out,stream_format_v->header_size);
    mFileIO->write_int(out,stream_format_v->width);
    mFileIO->write_int(out,stream_format_v->height);
    mFileIO->write_short(out,stream_format_v->num_planes);
    mFileIO->write_short(out,stream_format_v->bits_per_pixel);

    if(stream_format_v->compression_type.isNull() || stream_format_v->compression_type.isEmpty())
    {
        mFileIO->write_int(out,(uint)0);
    }
    else
    {
        mFileIO->write_chars_bin(out,stream_format_v->compression_type.toLatin1().data(),4);
    }

    mFileIO->write_int(out,stream_format_v->image_size);
    mFileIO->write_int(out,stream_format_v->x_pels_per_meter);
    mFileIO->write_int(out,stream_format_v->y_pels_per_meter);
    mFileIO->write_int(out,stream_format_v->colors_used);
    mFileIO->write_int(out,stream_format_v->colors_important);

    if(stream_format_v->colors_used !=0)
    {
        for(i=0;i<stream_format_v->colors_used;i++)
        {
            mFileIO->write_int(out,stream_format_v->palette[i] & 255);
            mFileIO->write_int(out,(stream_format_v->palette[i] >> 8) & 255);
            mFileIO->write_int(out,(stream_format_v->palette[i] >> 16) & 255);
            mFileIO->write_int(out,0);
        }
    }

    t = out->length();
    mFileIO->insert_int(out,marker,(uint)(t-marker));
}

int AviUtils::write_avi_header_chunk(gwavi_t *gwavi)
{
    long marker,t;
    long sub_marker;
    QByteArray *out =new QByteArray;
    //= gwavi->out;

    mFileIO->write_chars_bin(out,"LIST",4);

    // insert size value
    marker = out->length();

    mFileIO->write_chars_bin(out,"hdrl",4);

    write_avi_header(out,&gwavi->avi_header);//avih

    mFileIO->write_chars_bin(out,"LIST",4);

    sub_marker = out->length();

    mFileIO->write_chars_bin(out,"strl",4);
    write_stream_header(out,&gwavi->stream_header_v);//strh

    write_stream_format_v(out,&gwavi->stream_format_v);//strf

    t = out->length();

    mFileIO->insert_int(out,sub_marker,(uint)(t-sub_marker));

    t = out->length();

    mFileIO->insert_int(out,marker,(uint)(t-marker));

    gwavi->out->append(*out);
    return 0;
}

int AviUtils::write_index(QByteArray *out, int count, uint *offsets)
{
    long marker,t;
    uint offset = 4;
    if(offsets == 0)
    {
        return -1;
    }

    mFileIO->write_chars_bin(out,"idx1",4);

    marker = out->length();

    for(t=0;t<count;t++)
    {
        if((offsets[t] & 0x80000000) == 0)
        {
            out->append("00dc");
        }
        else
        {
            out->append("01wb");
            offsets[t] &= 0x7fffffff;
        }

        mFileIO->write_int(out,0x10);
        mFileIO->write_int(out,offset);
        mFileIO->write_int(out,offsets[t]);

        offset = offset + offsets[t] + 8;
    }

    t = out->length();
    mFileIO->insert_int(out,marker,(uint)(t-marker-4));

    return 0;
}
